#include "Function.hpp"
#include "EquationSolver.hpp"
#include <iostream>
#include <cmath>

const double Pi = acos(-1.); 

class F: public Function{
private:
	double l;
	double h;
	double D;
	double b;
public:
	//double l = 89, double h = 49, double D = 55, double b = 11.5
	F(double l, double h, double D, double b) : l(l), h(h), D(D), b(b) {}
	
	double operator() (double a) const{
	        
		double beta = b/180*Pi;
		double A = sin(beta) * l;
		double B = l * cos(beta);
		double C = (h + 0.5*D)*sin(beta) - 0.5*D*tan(beta);
		double E = (h + 0.5*D)*cos(beta) - 0.5*D;
		return A*sin(a)*cos(a) + B*pow(sin(a),2) - C*cos(a) - E*sin(a);
	}
	double derivative(double a) const{
		
		double beta = b/180*Pi;
		double A = sin(beta) * l;
		double B = l * cos(beta);
		double C = (h + 0.5*D)*sin(beta) - 0.5*D*tan(beta);
		double E = (h + 0.5*D)*cos(beta) - 0.5*D;
		return A*cos(2*a) + B*2*cos(a) + C*sin(a) - E*cos(a);
	}
	
};

void solve_1(){
	std::cout << "solution for (a): " << std::endl;
	double x0 = 33./180*Pi;
	Newton_Method solver_1(F(89,49,55,11.5), x0);
	double x = solver_1.solve()/Pi*180;
	std::cout << "the root is " << x << std::endl;
}

void solve_2(){
	std::cout << "solution for (b): " << std::endl;
	double x0 = 33./180*Pi;
	Newton_Method solver_2(F(89,49,30,11.5), x0);
	double x = solver_2.solve()/Pi*180;
	std::cout << "the root is " << x << std::endl;
}

void solve_3(double x0, double x1){
  std::cout << "solution for (c) with initial "<< x0 << " and " << x1 << std::endl;
	x0 = x0/180*Pi;
	x1 = x1/180*Pi;
	Secant_Method solver_3(F(89,49,55,11.5), x0, x1);
	double x = solver_3.solve()/Pi*180;
	std::cout << "the root is " << x << std::endl;
}

int main(){
	solve_1();
	solve_2();
	solve_3(0,10);
	solve_3(100, 150);
	solve_3(5,10);
}
